package com.yhd.commonauth.util;

import com.yhd.commonauth.annotation.Authorization;
import com.yhd.commonauth.annotation.PassAuthorization;
import com.yhd.commonauth.auth.Authentication;
import com.yhd.commonauth.auth.AuthenticationProxy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 提供一些权限校验的方法工具类
 *
 * @author Liuzr
 * @since 2020-12-30
 */
@Slf4j
public class AuthUtil {

    /**
     * 检查绕过校权的接口
     *
     * @param handler
     * @return
     */
    public static boolean checkPassAuthorization(HandlerMethod handler) {
        Method method = handler.getMethod();
        if (method.isAnnotationPresent(PassAuthorization.class)) {
            PassAuthorization passToken = method.getAnnotation(PassAuthorization.class);
            if (passToken.required()) {
                return true;
            }
        }
        if (method.getDeclaringClass().isAnnotationPresent(PassAuthorization.class)) {
            PassAuthorization passToken = method.getDeclaringClass().getAnnotation(PassAuthorization.class);
            if (passToken.required()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 权限校验
     * 通过注解代理找到具体的权限实现类进行逻辑校验。
     *
     * @param request
     * @param response
     * @param handler
     * @return
     */
    public static boolean checkAuthorization(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
        Method method = handler.getMethod();
        Authentication authentication = AuthenticationProxy.getInstance(method.getDeclaringClass().getAnnotation(Authorization.class));
        if (authentication == null) {
            log.info("没有获取到具体权限校验bean。请检查注解@Authorization和权限实现类！");
            return false;
        }
        return authentication.checkAuthorization(request, response);
    }

    /**
     * 通用校权逻辑
     * 绕过校验优先级 > 权限校验
     *
     * @param request
     * @param response
     * @param handler
     * @return
     */
    public static boolean checkCommonAuthorization(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler) {
        if (checkPassAuthorization(handler)) {
            return true;
        }
        return checkAuthorization(request, response, handler);
    }
}
